import {ActivatedRoute, Router} from "@angular/router";

/**
 * 表示一次http请求的结果
 */
export class Result<T> {
  /**
   * 表示状态码 200表示请求成功 其他表示失败
   * 该状态码不是http的状态码，只是用来判断请求是否成功的依据
   */
  private readonly code: number | undefined;

  /**
   * 附带消息。
   * 当请求失败时，失败原因会设置在此字段。
   * 请求成功时，一般可以忽略
   */
  readonly msg: string | undefined;

  /**
   * 请求的返回结果
   */
  readonly data: T | undefined;


  success(): boolean {
    return this.code === 200
  }

  resolveError(router: Router, route: ActivatedRoute) {
    if (this.code === 401) {
      alert("您未登录! 请先登录")
      router.navigate(['user/login', route])
    } else {
      this.handlerErrorMsg()
    }

  }

  handlerErrorMsg() {
    alert(this.msg)

  }
}

function convertResult(resp: Response): Promise<Result<any>> {
  return resp.json().then(
    result => {
      return Object.assign(new Result(), result);
    }
  )
}

/**
 * 发送一次get方法请求
 * @param url 请求地址
 * @param params 请求参数对象 会被解析后填充成?a=b的格式
 */
export const doGet = (url: string, params: any): Promise<Result<any>> => {

  const param = new URLSearchParams();
  for (let k in params) {
    param.append(k, params[k])
  }
  return fetch(url + '?' + param.toString()).then(t => convertResult(t));
};

/**
 * 发送一次get方法请求
 * @param url 请求地址
 */
export const doGetDirect = (url: string): Promise<Result<any>> => {
  return fetch(url).then(t => convertResult(t));
};

/**
 * 发送一次post方法请求，请求参数对象会被以x-www-form-urlencoded格式编码放入body中
 * @param url 请求地址
 * @param params 参数对象
 */
export const doPostUrlEncoding = (url: string, params: any): Promise<Result<any>> => {
  const param = new URLSearchParams();
  for (let k in params) {
    param.append(k, params[k])
  }
  return fetch(url, {
    method: "POST",
    body: param
  }).then(t => convertResult(t));

};

/**
 * 发送一次post方法请求，请求参数对象会被以form-data格式编码放入body中
 * @param url 请求地址
 * @param params 参数对象
 */
export const doPostFormData = (url: string, params: any): Promise<Result<any>> => {
  const param = new FormData();
  for (let k in params) {
    param.append(k, params[k])
  }
  return fetch(url, {
    method: "POST",
    body: param
  }).then(t => convertResult(t));
};

/**
 * 发送一次post方法请求，请求参数对象会被以json字符串编码放入body中
 * @param url 请求地址
 * @param params 参数对象
 */
export const doPostJson = (url: string, params: any): Promise<Result<any>> => {
  return fetch(url, {
    method: "POST",
    body: JSON.stringify(params),
    headers: {
      'Content-Type': 'application/json'
    }
  }).then(t => convertResult(t));
};
